package com.bluetron.supos.apps.filters;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;

import com.bluetron.supos.apps.commons.Constants;

import lombok.extern.slf4j.Slf4j;

/**
 * 访问日志过滤器
 * <p>
 * 1. 打印访问日志, 包括请求URL, 请求参数, 响应状态码, 响应时间等
 * 2. 增加链路ID
 */
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter(urlPatterns = "/*")
public class AccessLogFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        final String queryString = StringUtils.hasText(httpServletRequest.getQueryString())
                ? "?" + httpServletRequest.getQueryString()
                : "";
        final String url = httpServletRequest.getMethod() + " " + httpServletRequest.getRequestURI() + queryString;
        try {
            MDC.put(Constants.MDC_TRACE_ID, UUID.randomUUID().toString().toLowerCase().replaceAll("-", ""));
            log.info("==> {}", url);

            long startTime = System.currentTimeMillis();
            chain.doFilter(request, response);
            long endTime = System.currentTimeMillis();
            long costTime = endTime - startTime;

            log.info("<== {}, cost: {}ms, status: {}", url, costTime, httpServletResponse.getStatus());
        } finally {
            MDC.remove(Constants.MDC_TRACE_ID);
        }
    }

}
